import { AMAP_WEB_KEY, GOOGLE_MAP_KEY } from '@/config/config';
import { useNavigation, useRoute } from '@react-navigation/native';
import { useDebounceFn } from 'ahooks';
import React, { useCallback, useEffect, useRef, useState } from 'react';
import { useTranslation } from 'react-i18next';
import {
  FlatList,
  Linking,
  PermissionsAndroid,
  Platform,
  TextInput,
  TouchableOpacity,
  View,
} from 'react-native';
import {
  Geolocation,
  setLocatingWithReGeocode,
  setNeedAddress,
} from 'react-native-amap-geolocation';
import { Button, Icon, Search, Text, useAppTheme } from 'tsun-smart-ui';
import {
  check,
  openSettings,
  PERMISSIONS,
  request,
  RESULTS,
} from 'react-native-permissions';
import { UserInfo } from '@/services/api/userApi';
import {
  GeoLocation,
  GooglePlaceDetails,
  AMapSearchResult,
  AMapSearchResultTips,
  GoogleSearchResultSuggestions,
  GoogleSearchResult,
} from './SelectAddressScreen.types';
import { useMMKVObject } from '@/hooks/useMMkv';
import { useSelector } from 'react-redux';
import { RootState } from '@/store';
import AlertDialog from '@/components/AlertDialog';
import PermissionUtils from '@/utils/PermissionUtils';

const fetchGooglePlaceDetails = async (
  placeId: string
): Promise<GooglePlaceDetails> => {
  var myHeaders = new Headers();
  myHeaders.append('X-Goog-Api-Key', 'AIzaSyDaejHMoIme2WQCDhkRt9I2rRbo8UWRnO8');
  myHeaders.append(
    'X-Goog-FieldMask',
    'formattedAddress,id,location,shortFormattedAddress'
  );
  myHeaders.append('Content-Type', 'application/json');

  var requestOptions = {
    method: 'GET',
    headers: myHeaders,
    redirect: 'follow',
  };

  return fetch(
    'https://places.googleapis.com/v1/places/' + placeId,
    requestOptions
  )
    .then((response) => response.json())
    .catch((error) => console.log('error', error));
};

const SelectAddressScreen: React.FC = () => {
  const navigation = useNavigation();
  const route = useRoute();
  const { t } = useTranslation();
  const appTheme = useAppTheme();
  const [position, setPosition] = useState<GeoLocation>();
  const [keyword, setKeyword] = useState('');
  const [locatingStatus, setLocatingStatus] = useState<
    'locating' | 'success' | 'failed'
  >('locating');
  const abortController = useRef<AbortController>(null);
  /// 结果可能是高德或者谷歌的搜索结果
  const [searchResults, setSearchResults] = useState<any[]>([]);
  const [userInfo, setUserInfo] = useMMKVObject<UserInfo>('user_info');
  const [hasLocationPermission, setHasLocationPermission] = useState(true);
  const isChineseUser = useSelector<RootState, boolean>(
    (state: any) => state.global.isChineseUser
  );

  useEffect(() => {
    if (!position) {
      updateCurrentPosition();
    }
    return () => {
      abortController.current?.abort();
    };
  }, []);

  /// 更新当前位置信息
  const updateCurrentPosition = useCallback(async () => {
    const permission = Platform.OS === 'android' ? PERMISSIONS.ANDROID.ACCESS_FINE_LOCATION : PERMISSIONS.IOS.LOCATION_WHEN_IN_USE;
    const status = await PermissionUtils.checkPermission(permission)
    let havePermissions = status.granted;
    setHasLocationPermission(havePermissions);
    if (!havePermissions) {
      return;
    }
    setLocatingWithReGeocode(true);
    setNeedAddress(true);
    Geolocation.getCurrentPosition(
      (position) => {
        // @ts-ignore
        setPosition(position.location);
        setLocatingStatus('success');
        console.log('当前位置：', JSON.stringify(position.location));
      },
      (error) => {
        setLocatingStatus('failed');
        console.log('定位失败', error);
      }
    );
  }, []);

  const { run: fetchAMapAddressAutoCompletions } = useDebounceFn(
    (keyword: string) => {
      abortController.current?.abort();
      abortController.current = new AbortController();
      if (keyword.length <= 1) {
        setSearchResults([]);
        return;
      }
      const location = !!position
        ? `${position.longitude},${position.latitude}`
        : '';
      fetch(
        `https://restapi.amap.com/v3/assistant/inputtips?keywords=${keyword}&Key=${AMAP_WEB_KEY}&location=${location}`,
        {
          method: 'GET',
          // redirect: 'follow',
          signal: abortController.current.signal,
        }
      )
        .then((response) => response.json())
        .then((result) => {
          const searchResults = result as AMapSearchResult;
          if (searchResults.tips) {
            setSearchResults(searchResults.tips);
          }
        })
        .catch((error) => console.log('error', error));
    },
    { wait: 300 }
  );

  /// 拿谷歌地图自动补全
  const { run: fetchGoogleAddressAutoCompletions } = useDebounceFn(
    (keyword: string) => {
      var myHeaders = new Headers();
      myHeaders.append('X-Goog-Api-Key', GOOGLE_MAP_KEY);
      myHeaders.append('FieldMask', '*');
      myHeaders.append('Content-Type', 'application/json');

      var raw = JSON.stringify({
        input: keyword,
        includeQueryPredictions: true,
        locationRestriction: {
          circle: {
            center: {
              latitude: position?.latitude,
              longitude: position?.longitude,
            },
            radius: 50000,
          },
        },
      });

      var requestOptions = {
        method: 'POST',
        headers: myHeaders,
        body: raw,
        redirect: 'follow',
      };

      fetch(
        'https://places.googleapis.com/v1/places:autocomplete',
        requestOptions
      )
        .then((response) => response.json())
        .then((result) => {
          const searchResult = result as GoogleSearchResult;
          setSearchResults(searchResult.suggestions);
        })
        .catch((error) => console.log('error', error));
    },
    { wait: 300 }
  );

  const search = useCallback(
    (keyword: string) => {
      if (isChineseUser) {
        fetchAMapAddressAutoCompletions(keyword);
      } else {
        fetchGoogleAddressAutoCompletions(keyword);
      }
    },
    [isChineseUser]
  );

  const openPermissionSettings = useCallback(async () => {
    openSettings('application');
  }, []);

  const renderDefaultContent = useCallback(() => {
    let title: string;
    if (locatingStatus === 'success') {
      title = position?.address ?? '';
    } else if (locatingStatus === 'locating') {
      title = t('sys.app.locating', { defaultValue: '定位中...' });
    } else {
      title = t('sys.app.locating.failed', { defaultValue: '定位失败' });
    }
    if (!hasLocationPermission) {
      title = t('sys.app.not.granted.locating.permission', {
        defaultValue: '定位权限未开启',
      });
    }
    return (
      <View>
        <View className="flex-row justify-between items-center">
          <Text variant="body">
            {t('sys.app.my.location', { defaultValue: '我的位置' })}
          </Text>
          {!hasLocationPermission && (
            <Button
              title={t('sys.app.open.permissions', {
                defaultValue: '打开权限',
              })}
              variant="text"
              onPress={openPermissionSettings}
            />
          )}
        </View>
        <TouchableOpacity
          onPress={() => {
            if (position) {
              // @ts-ignore
              navigation.popTo(route.params.callback, { position: position });
            } else {
              setLocatingStatus('locating');
              updateCurrentPosition();
            }
          }}
          className="bg-text6 py-2 px-2 mt-2 self-start rounded-lg"
        >
          <Text>
            <Icon name="position" size={14} color={appTheme.colors?.brand?.onPrimary} />
            {' '}
            {title}
          </Text>
        </TouchableOpacity>
      </View>
    );
  }, [locatingStatus, position, hasLocationPermission, t]);

  /// 单元格
  const renderItem = useCallback(
    ({ item, index }: { item: any; index: number }) => {
      const isFirst = index === 0;
      const isLast = index === searchResults.length - 1;
      const borderTopRadius = isFirst ? 8 : 0;
      const borderBottomRadius = isLast ? 8 : 0;
      let title, description: string;
      let isGoogleSearchResult = item.placePrediction !== undefined;
      if (isGoogleSearchResult) {
        const googleSearchResult = item as GoogleSearchResultSuggestions;
        title =
          googleSearchResult.placePrediction.structuredFormat.mainText.text;
        description = googleSearchResult.placePrediction.text.text;
      } else {
        title = item.name;
        description = item.district + item.address;
      }
      return (
        <TouchableOpacity
          onPress={async () => {
            if (isGoogleSearchResult) {
              const placeDetails = await fetchGooglePlaceDetails(
                item.placePrediction.placeId
              );
              if (placeDetails) {
                const position: GeoLocation = {
                  longitude: placeDetails.location.longitude,
                  latitude: placeDetails.location.latitude,
                  address: placeDetails.formattedAddress,
                };
                // @ts-ignore
                navigation.popTo(route.params.callback, { position: position });
              }
            } else {
              if (!item.location) {
                return;
              }
              const location = item.location.split(',');

              const position: GeoLocation = {
                longitude: parseFloat(location[0]),
                latitude: parseFloat(location[1]),
                address: item.district + item.name,
              };
              // @ts-ignore
              navigation.popTo(route.params.callback, { position: position });
            }
          }}
          className="bg-text6 px-5 py-3"
          style={{
            borderTopLeftRadius: borderTopRadius,
            borderTopRightRadius: borderTopRadius,
            borderBottomLeftRadius: borderBottomRadius,
            borderBottomRightRadius: borderBottomRadius,
          }}
        >
          <Text variant="body" className="color-text1">
            {title}
          </Text>
          <Text variant="caption" className="color-text3">
            {description}
          </Text>
        </TouchableOpacity>
      );
    },
    [searchResults]
  );

  return (
    <View className="flex-1 bg-fill1 px-3 py-3">
      <View className="bg-text6 flex-row items-center gap-1 px-5 rounded-full h-12">
        <Icon
          name="search"
          size={16}
          color={appTheme.colors?.neutral?.secondaryTitle}
        />
        <TextInput
          placeholder={t('sys.app.pls.input.address', {
            defaultValue: '请输入地址',
          })}
          className="flex-1 my-1 ml-1"
          value={keyword}
          onChangeText={(text) => {
            setKeyword(text);
            search(text);
          }}
          clearButtonMode="while-editing"
        />
      </View>
      <FlatList
        className="flex-1 mt-3"
        data={searchResults}
        renderItem={renderItem}
        ListEmptyComponent={renderDefaultContent}
        ItemSeparatorComponent={ItemSeparator}
        keyExtractor={(item, index) => index.toString()}
        keyboardDismissMode="on-drag"
      />
      <AlertDialog
        visible={!hasLocationPermission}
        onDismiss={() => setHasLocationPermission(true)}
        title={t('message.enablePermission')}
        buttons={[
          {
            title: t('user.logOutCancel'),
            onPress: () => {},
          },
          {
            title: t('sys.app.go.2.settings'),
            highlighted: true,
            onPress: Linking.openSettings,
          },
        ]}
      />
    </View>
  );
};

export default React.memo(SelectAddressScreen);

const ItemSeparator: React.FC = React.memo(() => {
  return (
    <View className="bg-text6 items-stretch">
      <View className={`bg-line1 h-[1px] my-1 mx-1`} />
    </View>
  );
});
